using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DSEngine.Core;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using DSEngine.Stage;
using Microsoft.Xna.Framework.Input.Touch;

namespace DSEngine.Sprite
{
    public class SpObject : BaseObject
    {
        #region Constructure
        public SpObject()
        {
            this.Touchable = true;
            this.Scale = new Vector2(1, 1);
            this.Position = new Vector2(0, 0);
            this.Visible = true;
            this.Enable = true;

            this.boundingBox = new List<BoundingBox>();
        }
        #endregion
        #region Method
        public override  void Draw(Microsoft.Xna.Framework.GameTime gameTime)
        {
            if (Visible)
            {
                InnerDraw(gameTime);
            }
        }
        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            if (Enable)
            {
                boundingBox = UpdateBoundingBox(gameTime);
                InnerUpdate(gameTime);
            }
        }
        public override void Dispose()
        {
            base.Dispose();
        }
        protected virtual void InnerDraw(GameTime gt)
        {
            
        }
        protected virtual void InnerUpdate(GameTime gt)
        {

        }
        private bool InnerCheckTouch(List<BoundingBox> boundingBoxes,Vector2 v)
        {
            foreach (var item in boundingBoxes)
            {
                ContainmentType type = item.Contains(new Vector3(v, 0)) ;
                if (type == ContainmentType.Contains || type == ContainmentType.Intersects)
                {
                    return true;
                }
            }
            return false;
        }
        public delegate void OnTouch(SpObject sender, InputData input);
        public event OnTouch OnBeforeObjectHandleTouchEvent;
        public event OnTouch OnAfterObjectHandleTouchedEvent;
        internal bool SystemHandleInput(GameTime gameTime, InputData input)
        {
            if (OnBeforeObjectHandleTouchEvent != null)
            {
                OnBeforeObjectHandleTouchEvent(this, input);
            }
            HandleInput(gameTime, input);
            if (OnAfterObjectHandleTouchedEvent != null)
            {
                OnAfterObjectHandleTouchedEvent(this, input);
            }
            return input.Handled;
        }
        public virtual void HandleInput(GameTime gameTime, InputData input)
        {
        }
        public virtual void Init()
        {

        }


        public bool CheckTouch(TouchLocation location)
        {
            if (this.Touchable == false)
                return false;
            return InnerCheckTouch(this.BoundingBox, location.Position); 
        }
        
        protected virtual List<BoundingBox> UpdateBoundingBox(GameTime gameTime)
        {
            BoundingBox bb = new BoundingBox();
            bb.Min = new Vector3(this.Position, 0);
            bb.Max = bb.Min + new Vector3(this.Width * this.Scale.X, this.Height * this.Scale.Y, 0);
            List<BoundingBox> bl = new List<BoundingBox>();
            bl.Add(bb);
            return bl;
        }

        public bool CheckImpack(SpObject targetObj)
        {
            foreach (var item in targetObj.BoundingBox)
            {
                foreach (var box in this.BoundingBox)
                {
                    if (item.Intersects(box))
                        return true;
                }
            }
            return false;
        }
        #endregion

        #region Property
        protected List<BoundingBox> boundingBox;
        public List<BoundingBox> BoundingBox
        {
            get
            { return this.boundingBox; }
        }
        public bool Touchable { get; set; }
        public bool Visible { get; set; }
        public bool Enable { get; set; }
        
        public int ZOrder { get; set; }
        protected float _width, _height;
        public virtual float Width 
        {
            get
            {
                return _width;
            }
            set
            {
                _width = value;
            }
        }
        public virtual float Height 
        {
            get
            {
                return _height;
            }
            set
            {
                _height = value;
            }
        }
        #endregion

         
    }
}
